package com.qpx.redis.service;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


/**
 * setNx 悲观锁 解决雪崩 击穿 穿透问题
 * 事物+监听  解决秒杀 库存卖超问题。
 */
@Component
public class RedisLockTest {


    @Autowired
    RedisTemplate redisTemplate;

    public String setNx() throws InterruptedException {
        System.out.println(Thread.currentThread().getName()+"开始获取缓存数据");
        String value = (String) redisTemplate.opsForValue().get("order1");
        if (StringUtils.isNotBlank(value)){
            System.out.println(Thread.currentThread().getName()+"开始获取缓存数据成功，返回");
            return  value;
        }
        System.out.println(Thread.currentThread().getName()+"获取缓存数据失败");
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("lock", "1");

        if (aBoolean){
            System.out.println(Thread.currentThread().getName()+"拿到锁成功,重新设置缓存");
            redisTemplate.expire("lock",1, TimeUnit.MINUTES);
            //处理业务逻辑
            value = (String) redisTemplate.opsForValue().get("order1");
            if (StringUtils.isNotBlank(value)){
                System.out.println(Thread.currentThread().getName()+"---------返回缓存数据");
                redisTemplate.delete("lock");
                return (String) redisTemplate.opsForValue().get("order1");
            }
            //模拟查询数据库
            Thread.sleep(2000);
            redisTemplate.opsForValue().set("order1","订单号为123456");
            redisTemplate.delete("lock");
            System.out.println(Thread.currentThread().getName()+"。。。。。。返回缓存数据");
            return (String) redisTemplate.opsForValue().get("order1");
        }else {
            Thread.sleep(500);
            setNx();
        }
        return null;
    }
}